package com.example.forum_system.services.impl;

import com.example.forum_system.common.AppResult;
import com.example.forum_system.common.ResultCode;
import com.example.forum_system.dao.UserMapper;
import com.example.forum_system.exception.ApplicationException;
import com.example.forum_system.model.User;
import com.example.forum_system.services.IUserService;
import com.example.forum_system.utils.MD5Utils;
import com.example.forum_system.utils.StringUtils;
import com.example.forum_system.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Author: 啵啵虎
 * @Date: 2024-05-15  18:37
 */

@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public User selectByUsername(String username) {
        //非空校验
        if (StringUtils.isEmpty(username)){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //调用DAO
        User user=userMapper.selectByUsername(username);
        //返回结果
        return user;
    }

    @Override
    public User selectById(Long id) {
        //1、非空校验
        if (id==null || id<=0){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2、调用DAO
        User user=userMapper.selectByPrimaryKey(id);
        //3、返回结果
        return user;
    }

    @Override
    public void createNormalUser(User user) {
        //1、非空校验
        if (user==null || StringUtils.isEmpty(user.getUsername())
            || StringUtils.isEmpty(user.getNickname()) || StringUtils.isEmpty(user.getPassword())
            || StringUtils.isEmpty(user.getSalt())){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2、校验用户是否存在
        User existUser=selectByUsername(user.getUsername());
        if (existUser!=null){
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }
        //3、设置默认值
        if (user.getGender()==null || user.getGender()<0 || user.getGender()>2){
            //性别保密
            user.setGender((byte) 2);
        }
        user.setArticleCount(0);  //发布的文章数量
        user.setIsAdmin((byte) 0);  //是否管理员
        user.setState((byte) 0);  //状态
        user.setDeleteState((byte) 0);  //是否删除
        //时间
        Date date=new Date();
        user.setCreateTime(date);  //创建时间
        user.setUpdateTime(date);  //更新时间
        //4、写入用户数据，返回结果
        int row=userMapper.insertSelective(user);
        //判断受影响的行数
        if (row!=1){
            log.warn("用户注册时,"+ResultCode.FAILED_CREATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
    }

    @Override
    public User login(String username, String password) {
        //1、非空校验
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2、查询用户是否存在
        User user=selectByUsername(username);
        //校验用户
        if (user==null){
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN.getMessage()));
        }
        //校验密码
        //获取用户的盐
        String salt=user.getSalt();
        //生成密文
        String ciphertext= MD5Utils.md5Salt(password,salt);
        //比较密文是否一致
        if (!ciphertext.toLowerCase().equals(user.getPassword().toLowerCase())){
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN.getMessage()));
        }
        //校验通过，返回user对象
        return user;
    }

    @Override
    public void addOneArticleCountById(Long id) {
        //非空校验
        if (id==null || id<=0){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //获取用户信息
        User user=selectById(id);
        if (user==null || user.getDeleteState()==1){
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //构造更新对象
        User updateUser=new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()+1);
        updateUser.setUpdateTime(new Date());
        //调用DAO
        int row=userMapper.updateByPrimaryKeySelective(updateUser);
        if (row!=1){
            //打印日志
            log.warn(ResultCode.ERROR_SERVICES.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        //非空校验
        if (id==null || id<=0){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //获取用户信息
        User user=selectById(id);
        if (user==null || user.getDeleteState()==1){
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //构造更新对象
        User updateUser=new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()-1);
        //判断减1之后，用户的发帖数是否小于0
        if (updateUser.getArticleCount()<0){
            //如果小于0，则设置为0
            updateUser.setArticleCount(0);
        }
        //调用DAO
        int row=userMapper.updateByPrimaryKeySelective(updateUser);
        if (row!=1){
            //打印日志
            log.warn(ResultCode.ERROR_SERVICES.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
    }

    @Override
    public void modifyInfo(User user) {
        //非空校验
        if (user==null || user.getId()==null || user.getId()<=0){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //查询用户基本信息
        User existUser=userMapper.selectByPrimaryKey(user.getId());
        if (existUser==null){
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }

        //定义一个标识
        boolean checkParams=false;
        //定义一个更新对象
        User updateUser=new User();
        //设置Id
        updateUser.setId(user.getId());
        //更新时间
        updateUser.setUpdateTime(new Date());

        //处理username
        if (!StringUtils.isEmpty(user.getUsername())
                && !user.getUsername().equals(existUser.getUsername())){
            //如果username不为空，那么则需要更新
            //1、查询当前数据库中是否存在相同的用户名
            User checkUser=selectByUsername(user.getUsername());
            if (checkUser!=null){
                //用户名已存在，抛出异常
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
            //设置要更新用户名
            updateUser.setUsername(user.getUsername());
            //设置参数检查标识
            checkParams=true;
        }

        //处理昵称
        if (!StringUtils.isEmpty(user.getNickname())
                && !user.getNickname().equals(existUser.getNickname())){
            //如果nickname不为空，那么则需要更新
            updateUser.setNickname(user.getNickname());
            //设置参数检查标识
            checkParams=true;
        }

        //处理电话号码
        if (!StringUtils.isEmpty(user.getPhoneNum())
                && !user.getPhoneNum().equals(existUser.getPhoneNum())){
            //如果nickname不为空，那么则需要更新
            updateUser.setPhoneNum(user.getPhoneNum());
            //设置参数检查标识
            checkParams=true;
        }

        //处理邮箱
        if (!StringUtils.isEmpty(user.getEmail())
                && !user.getEmail().equals(existUser.getEmail())){
            //如果nickname不为空，那么则需要更新
            updateUser.setEmail(user.getEmail());
            //设置参数检查标识
            checkParams=true;
        }

        //处理个人简介
        if (!StringUtils.isEmpty(user.getRemark())
            && !user.getRemark().equals(existUser.getRemark())){
            //如果nickname不为空，那么则需要更新
            updateUser.setRemark(user.getRemark());
            //设置参数检查标识
            checkParams=true;
        }

        //处理性别
        if (user.getGender()!=null && user.getGender()!=existUser.getGender()){
            //设置要更新的值
            updateUser.setGender(user.getGender());
            //性别是否有效
            if (updateUser.getGender()<0 || updateUser.getGender()>2){
                //默认为2（保密）
                updateUser.setGender((byte) 2);
            }
            //设置参数检查标识
            checkParams=true;
        }

        //如果所有的参数都为空
        if (!checkParams){
            //打印日志
            log.warn("用户更新时，所有的参数都为空，user id="+user.getId());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //调用DAO
        int row=userMapper.updateByPrimaryKeySelective(updateUser);
        //判断受影响的行数
        if (row!=1){
            log.warn("用户更新时，"+ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
    }

    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
        //非空校验
        if (id==null || id<=0 || StringUtils.isEmpty(newPassword)
            || StringUtils.isEmpty(oldPassword)){
            //打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //1、查询用户详情
        User user=selectById(id);
        //2、校验用户是否存在
        if (user==null || user.getDeleteState()==1){
            //抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //3、根据用户的盐和传入密码计算出密码的密文
        String encryptOldPassword=MD5Utils.md5Salt(oldPassword,user.getSalt());
        //4、用密文与数据库中的password字段作比较，如果相同表示密码校验通过
        if (!encryptOldPassword.equalsIgnoreCase(user.getPassword())){
            //抛出异常
            throw new ApplicationException(AppResult.failed("原密码错误"));
        }
        //5、生成一个新的盐
        String salt= UUIDUtils.UUID_32();
        //6、根据新密码与新盐计算出新密码的密文
        String encryptPassword=MD5Utils.md5Salt(newPassword,salt);
        //7、构造更新对象
        User updateUser=new User();
        updateUser.setId(user.getId());  //用户Id
        updateUser.setSalt(salt);  //盐
        updateUser.setPassword(encryptPassword);  //新密码的密文
        updateUser.setUpdateTime(new Date());  //更新时间
        //8、调用DAO
        int row=userMapper.updateByPrimaryKeySelective(updateUser);
        //判断受影响的行数
        if (row!=1){
            log.warn("用户更新密码时，"+ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
    }
}
